package com.itheima.service.impl;

import com.alibaba.dubbo.config.annotation.Service;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.itheima.entity.PageResult;
import com.itheima.entity.QueryPageBean;
import com.itheima.entity.Result;
import com.itheima.mapper.MenuMapper;
import com.itheima.mapper.PermissionMapper;
import com.itheima.mapper.RoleMapper;
import com.itheima.pojo.Menu;
import com.itheima.pojo.Permission;
import com.itheima.pojo.Role;
import com.itheima.service.RoleService;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.beans.IntrospectionException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Stream;

import static com.itheima.constant.MessageConstant.*;

@Service(version = "1.0",interfaceClass = RoleService.class)
@Transactional
public class RoleServiceImpl implements RoleService {
    @Resource
    RoleMapper roleMapper;
    @Resource
    PermissionMapper permissionMapper;
    @Resource
    MenuMapper menuMapper;

    @Override
    public Result findPage(QueryPageBean queryPageBean) {
        try {
            Integer currentPage = queryPageBean.getCurrentPage();
            Integer pageSize = queryPageBean.getPageSize();
            PageHelper.startPage(currentPage, pageSize);

            Page<Role> roleList = roleMapper.findRoleByCondition(queryPageBean.getQueryString());
            PageResult pageResult = new PageResult();
            pageResult.setRows(roleList.getResult());
            pageResult.setTotal(roleList.getTotal());

            return Result.success(QUERY_ROLE_SUCCESS, pageResult);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return Result.fail(QUERY_ROLE_FAIL);
    }

    @Override
    public Result save(Role role, Integer[] menuIds) {
        try {
            roleMapper.save(role);
            Integer roleId = role.getId();
            Integer[] permissionIds=null;
            if (menuIds!=null){
                for (Integer menuId : menuIds) {
                    permissionIds = menuMapper.findPerByMenuId(menuId);
                    if (permissionIds!=null){
                        setRoleAndPermission(roleId,permissionIds);
                    }
                }
                setRoleAndMenu(roleId,menuIds);
            }
            return Result.success(ADD_ROLE_SUCCESS, null);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return Result.fail(ADD_ROLE_FAIL);
    }

    /**
     * 设置角色和菜单的关联信息
     *
     * @param roleId 角色id
     * @param menuIds 菜单id
     */
    private void setRoleAndMenu(Integer roleId, Integer[] menuIds) {
        Stream.of(menuIds).forEach(menuId -> roleMapper.saveRoleAndMenu(roleId, menuId));
    }

    /**
     * 设置角色和权限的关联信息
     *
     * @param roleId 角色id
     * @param permissionIds 权限id
     */
    private void setRoleAndPermission(Integer roleId, Integer[] permissionIds) {
        Stream.of(permissionIds).forEach(permissionId -> roleMapper.saveRoleAndPer(roleId, permissionId));
    }

    @Override
    public Result findById(Integer roleId) {
        try {
            List<Menu> menuList = menuMapper.findAll();
            List<Permission> permissionList = permissionMapper.findAllPermission();
            Set<Integer> permissionIds = roleMapper.findPerIdByRoleId(roleId);
            Set<Integer> menuIds = roleMapper.findMenuIdByRoleId(roleId);
            Role role = roleMapper.findById(roleId);

            Map<String, Object> map = new HashMap();
            map.put("permissionList", permissionList);
            map.put("menuList", menuList);
            map.put("permissionIds", permissionIds);
            map.put("menuIds", menuIds);
            map.put("role", role);

            return Result.success(QUERY_ROLE_SUCCESS, map);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return Result.fail(QUERY_ROLE_FAIL);
    }

    @Override
    public Result delete(Integer roleId) {
        long count = roleMapper.count(roleId);
        if (count > 0) {
            return Result.fail(500, DELETE_ROLE_FAIL);
        }
        roleMapper.delete(roleId);
        return Result.success(DELETE_ROLE_SUCCESS, null);
    }

    @Override
    public Result update(Role role, Integer[] menuIds) {
        try {
            roleMapper.update(role);
            Integer roleId = role.getId();

            roleMapper.deleteRoleAndPerByRoleId(roleId);
            roleMapper.deleteRoleAndMenuByRoleId(roleId);

            setRoleAndMenu(roleId,menuIds);
            Integer[] permissionIds=null;
            for (Integer menuId : menuIds) {
                permissionIds = menuMapper.findPerByMenuId(menuId);
                if (permissionIds!=null){
                    setRoleAndPermission(roleId,permissionIds);
                }
            }
            return Result.success(EDIT_ROLE_SUCCESS, null);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return Result.fail(EDIT_ROLE_FAIL);
    }
}
